package com.ly.heart.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.ly.common.PageParam;
import com.ly.common.core.domain.AjaxResult;
import com.ly.common.exception.CustomException;
import com.ly.common.utils.DateUtils;
import com.ly.common.utils.SecurityUtils;
import com.ly.common.utils.erp.ConstUtil;
import com.ly.common.utils.erp.SnowflakeIdWorker;
import com.ly.heart.domain.ActTaskCommentEntity;
import com.ly.heart.domain.KingBomDetailEntity;
import com.ly.heart.domain.MaterialEntity;
import com.ly.heart.domain.dto.KingBomDto;
import com.ly.heart.domain.dto.KingBomProductDto;
import com.ly.heart.domain.dto.StartProcessDto;
import com.ly.common.core.domain.ActCurrentTaskVo;
import com.ly.heart.domain.vo.ImportKingBomVo;
import com.ly.heart.domain.vo.KingBomVo;
import com.ly.heart.mapper.KingBomMapper;
import com.ly.heart.service.*;
import com.ly.heart.util.CurrentUserUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import com.ly.heart.domain.KingBomEntity;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;

/**
 * BOM清单Service业务层处理
 *
 * @author wutao
 * @date 2024-07-26
 */
@Service
public class KingBomServiceImpl extends ServiceImpl<KingBomMapper, KingBomEntity> implements IKingBomService {

    @Resource
    private KingBomMapper kingBomEntityMapper;
    @Resource
    private IKingBomDetailService iKingBomDetailService;
    @Resource
    private IMaterialService iMaterialService;
    @Resource
    private IActModelService iActModelService;
    @Resource
    private IActTaskCommentService iActTaskCommentService;

    /**
     * 查询BOM清单
     *
     * @param id BOM清单ID
     * @return BOM清单
     */
    @Override
    public KingBomVo selectKingBomEntityById ( String id ) {
        KingBomVo vo = new KingBomVo ();
        KingBomEntity kingBomEntity = kingBomEntityMapper.selectKingBomEntityById ( id );
        List<KingBomDetailEntity> list = iKingBomDetailService.list ( new LambdaQueryWrapper<KingBomDetailEntity> ().
                eq ( KingBomDetailEntity :: getBomId, id ) );
        vo.setKingBomEntity ( kingBomEntity ).setKingBomDetailEntities ( list );
        return vo;
    }

    @Override
    public AjaxResult queryList ( KingBomEntity kingBomEntity ) {
        LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper ();
        IPage iPage = new Page ( ( kingBomEntity.getPage () - 1 ) * kingBomEntity.getLimit (), kingBomEntity.getLimit () );
        IPage page = this.page ( iPage, lambdaQueryWrapper );
        List<KingBomEntity> records = page.getRecords ();
        List<ImportKingBomVo> importKingBomVos = new ArrayList<> ();
        List<String> parentCode = records.stream ().map ( KingBomEntity :: getParentMaterialCode ).collect ( Collectors.toList () );
        //物料名称
        List<MaterialEntity> list = iMaterialService.list ( new LambdaQueryWrapper<MaterialEntity> ().in ( MaterialEntity :: getMaterialCode, parentCode ) );
        records.forEach ( bom -> {
            ImportKingBomVo vo = new ImportKingBomVo ();
            String parMaterialName = "", parModel = "";
            for ( MaterialEntity materialEntity : list ) {
                if ( materialEntity.getMaterialCode ().equals ( bom.getParentMaterialCode () ) ) {
                    parMaterialName = materialEntity.getMaterialName ();
                    parModel = materialEntity.getModel ();
                }
            }
            vo.setId ( bom.getId () ).
                    setBomAs ( bom.getBomAs () ).
                    setBomClassify ( bom.getBomClassify () ).
                    setBomDesc ( bom.getBomDesc () ).
                    setBomGroup ( bom.getBomGroup () ).
                    setBomVersion ( bom.getBomVersion () ).
                    setParentMaterialCode ( bom.getParentMaterialCode () ).
                    setParMaterialName ( parMaterialName ).
                    setParModel ( parModel );
            //处理最后一个审批人
            ActTaskCommentEntity actTaskCommentEntity = iActTaskCommentService.queryLastComment ( bom.getInstanceId () );
            if ( actTaskCommentEntity != null ) {
                bom.setApprovedUser ( actTaskCommentEntity.getApprovedUser () );
                bom.setApprovedTime ( actTaskCommentEntity.getCreateTime () );
                bom.setApprovedRemark ( actTaskCommentEntity.getRemark () );
            }
            //任务信息
//            ActCurrentTaskVo currentTaskVo = iActModelService.getCurrentTaskByInstanceId ( bom.getInstanceId () );
//            Optional.ofNullable ( currentTaskVo ).ifPresent ( currentTask -> {
//                vo.setCurrentTask ( currentTask );
//            } );
            importKingBomVos.add ( vo );
        } );
        PageParam pageParam = new PageParam ();
        pageParam.setRecords ( importKingBomVos );
        pageParam.setTotal ( iPage.getTotal () );
        pageParam.setCurrent ( iPage.getCurrent () );
        pageParam.setSize ( iPage.getSize () );
        pageParam.setPages ( iPage.getPages () );
        return AjaxResult.success ( pageParam );
    }

    /**
     * 查询BOM清单列表
     *
     * @param kingBomEntity BOM清单
     * @return BOM清单
     */
    @Override
    public AjaxResult selectKingBomEntityList ( KingBomEntity kingBomEntity ) {
        kingBomEntity.setIsUsed ( ConstUtil.IS_USED_YES );
        kingBomEntity.setPage ( ( kingBomEntity.getPage () - 1 ) * kingBomEntity.getLimit () );
        List<KingBomEntity> kingBomEntities = kingBomEntityMapper.selectKingBomEntityList ( kingBomEntity );
        kingBomEntities.forEach ( bom -> {
            //处理最后一个审批人
            ActTaskCommentEntity actTaskCommentEntity = iActTaskCommentService.queryLastComment ( bom.getInstanceId () );
            if ( actTaskCommentEntity != null ) {
                bom.setApprovedUser ( actTaskCommentEntity.getApprovedUser () );
                bom.setApprovedRemark ( actTaskCommentEntity.getRemark () );
            }
            //任务信息
            ActCurrentTaskVo currentTaskVo = iActModelService.getCurrentTaskByInstanceId ( bom.getInstanceId () );
            Optional.ofNullable ( currentTaskVo ).ifPresent ( currentTask -> {
                bom.setCurrentTask ( currentTask );
            } );
        } );
        PageParam pageParam = new PageParam ();
        pageParam.setTotal ( kingBomEntityMapper.queryCount ( kingBomEntity ) ).setRecords ( kingBomEntities ).setSize ( kingBomEntities.size () ).setCurrent ( kingBomEntity.getPage () );
        return AjaxResult.success ( pageParam );
    }

    /**
     * BOM展开
     *
     * @param kingBomProductDto
     * @return
     */
    @Override
    public List<KingBomDetailEntity> expand ( KingBomProductDto kingBomProductDto ) {
        List<String> ids = kingBomProductDto.getIds ();
        List<KingBomDetailEntity> list = null;
        if ( ! CollectionUtils.isEmpty ( ids ) ) {
            list = iKingBomDetailService.list ( new LambdaQueryWrapper<KingBomDetailEntity> ().in ( KingBomDetailEntity :: getBomId, ids ) );
        }
        return list;
    }

    /**
     * 新增BOM清单
     *
     * @param kingBomDto BOM清单
     * @return 结果
     */
    @Override
    @Transactional ( rollbackFor = Exception.class, propagation = Propagation.REQUIRED )
    public AjaxResult draft ( KingBomDto kingBomDto ) {
        KingBomEntity kingBomEntity = kingBomDto.getKingBomEntity ();
        kingBomEntity.setId ( SnowflakeIdWorker.getInstance ().nextStringId () );
        int count = this.count ();
        String format = String.format ( "%08d", count );
        kingBomEntity.setBomVersion ( "BOM".concat ( format ) );
        kingBomEntity.setCreateDeptId ( CurrentUserUtil.getCompanyId () );
        kingBomEntity.setCreateUserId ( SecurityUtils.getLoginUser ().getUser ().getUserId () );
        kingBomEntity.setCreateDate ( DateUtils.getNowDate () );
        updateBomDetail ( kingBomDto.getKingBomDetailEntities (), kingBomEntity.getId () );
        kingBomEntity.setState ( ConstUtil.STATE_IN_DRAFT );
        boolean save = this.save ( kingBomEntity );
        if ( ! save ) {
            throw new CustomException ( "暂存Bom基础对象失败！" );
        }
        return AjaxResult.success ( "暂存BOM成功", kingBomEntity.getId () );
    }

    /**
     * 新增BOM清单
     *
     * @param kingBomEntity BOM清单
     * @return 结果
     */
    @Override
    @Transactional ( rollbackFor = Exception.class, propagation = Propagation.REQUIRED )
    public AjaxResult submit ( KingBomEntity kingBomEntity ) {
        if ( StringUtils.isBlank ( kingBomEntity.getId () ) ) {
            return AjaxResult.error ( "请先暂存该单据！" );
        }
        StartProcessDto startDto = new StartProcessDto ().
                setBusinessId ( kingBomEntity.getId () ).
                setBusinessType ( kingBomEntity.getBusinessType () ).setModelId ( kingBomEntity.getModelId () ).
                setBusinessName ( "BOM".concat ( kingBomEntity.getId () ) );
        String instanceId = iActModelService.startProcess ( startDto );
        boolean save = this.update ( new LambdaUpdateWrapper<KingBomEntity> ().set ( KingBomEntity :: getInstanceId, instanceId ).set ( KingBomEntity :: getState, ConstUtil.STATE_IN_PROCESS ).eq ( KingBomEntity :: getId, kingBomEntity.getId () ) );
        if ( ! save ) {
            throw new CustomException ( "提交Bom基础对象失败！" );
        }
        return AjaxResult.success ( "提交BOM成功" );
    }

    /**
     * 修改BOM清单
     *
     * @param kingBomDto BOM清单
     * @return 结果
     */
    @Override
    public AjaxResult updateKingBomEntity ( KingBomDto kingBomDto ) {
        KingBomEntity kingBomEntity = kingBomDto.getKingBomEntity ();
        kingBomEntity.setUpdateUserId ( SecurityUtils.getLoginUser ().getUser ().getUserId () );
        kingBomEntity.setUpdateDate ( DateUtils.getNowDate () );
        updateBomDetail ( kingBomDto.getKingBomDetailEntities (), kingBomEntity.getId () );
        boolean b = this.updateById ( kingBomEntity );
        if ( ! b ) {
            throw new CustomException ( "修改BOM基本信息失败！" );
        }
        return AjaxResult.success ();
    }

    /**
     * 伪删除
     *
     * @param ids
     * @return
     */
    @Override
    @Transactional ( rollbackFor = Exception.class, propagation = Propagation.REQUIRED )
    public AjaxResult updateByDelete ( String[] ids ) {
        KingBomEntity kingBomEntity = new KingBomEntity ();
        for ( int i = 0; i < ids.length; i++ ) {
            kingBomEntity.setId ( ids[i] );
            kingBomEntity.setIsUsed ( ConstUtil.IS_USED_NO );
            kingBomEntity.setUpdateDate ( DateUtils.getNowDate () );
            int update = kingBomEntityMapper.updateKingBomEntity ( kingBomEntity );
            if ( update == 0 ) {
                throw new CustomException ( "删除失败" );
            }
        }
        // 修改所有明细也为不可见
        LambdaUpdateWrapper<KingBomDetailEntity> detailLambda = new LambdaUpdateWrapper<> ();
        detailLambda.set ( KingBomDetailEntity :: getIsUsed, ConstUtil.IS_USED_NO );
        detailLambda.in ( KingBomDetailEntity :: getBomId, ids );
        iKingBomDetailService.update ( null, detailLambda );
        return AjaxResult.success ();
    }

    /**
     * 批量删除BOM清单
     *
     * @param ids 需要删除的BOM清单ID
     * @return 结果
     */
    @Override
    public int deleteKingBomEntityByIds ( String[] ids ) {
        return kingBomEntityMapper.deleteKingBomEntityByIds ( ids );
    }

    /**
     * 删除BOM清单信息
     *
     * @param id BOM清单ID
     * @return 结果
     */
    @Override
    public int deleteKingBomEntityById ( String id ) {
        return kingBomEntityMapper.deleteKingBomEntityById ( id );
    }

    /**
     * 更新BOM子项明细列表
     *
     * @param kingBomDetailEntities
     * @param bomId
     */
    private void updateBomDetail ( List<KingBomDetailEntity> kingBomDetailEntities, String bomId ) {
        if ( ! CollectionUtils.isEmpty ( kingBomDetailEntities ) ) {
            iKingBomDetailService.remove ( new LambdaUpdateWrapper<KingBomDetailEntity> ().eq ( KingBomDetailEntity :: getBomId, bomId ) );
            kingBomDetailEntities.forEach ( detail -> {
                detail.setId ( SnowflakeIdWorker.getInstance ().nextStringId () );
                detail.setBomId ( bomId );
                detail.setCreateBy ( SecurityUtils.getLoginUser ().getUser ().getUserId () );
                detail.setCreateTime ( DateUtils.getNowDate () );
                boolean save = iKingBomDetailService.save ( detail );
                if ( ! save ) {
                    throw new CustomException ( "更新BOM子项明细失败！" );
                }
            } );
        }
    }

}
